package com.plian.system.service.sys.orgzation.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.DateUtil;
import com.plian.Tools.StringUtil;
import com.plian.Tools.TokenUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.constant.sys.OrgConstant;
import com.plian.system.constant.yth.YthConstant;
import com.plian.system.entity.fr.enterprise.Enterprise;
import com.plian.system.entity.sys.Org;
import com.plian.system.mapper.sys.OrgMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.node.ForestNodeMerger;
import com.plian.system.properties.GzwProperties;
import com.plian.system.service.fr.enterprise.IEnterpriseService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.vo.sys.OrgVO;
import com.plian.system.vo.yth.YthResult;
import com.plian.system.wrapper.sys.OrgWrapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @description:
 * @author: gangan
 * @create: 2022-01-10 15:53
 */
@Service
@AllArgsConstructor
public class OrgServiceImpl extends ServiceImpl<OrgMapper, Org> implements IOrgService {

    private GzwProperties gzwProperties;

    private OrgWrapper orgWrapper;

    private IEnterpriseService enterpriseService;

    private final static String IS_DEL = "1";

    private final static String IS_UNIT = "1";

    private final static Integer FOR_GZW = 1;

    private final static Integer IS_MAIN = 2;

    private final static Integer IS_MONITOR = 1;

    private final static Integer UNIT_TYPE = 2;

    private final static String JGQY_ORG_CODE = "000101";

    //行政单位类型
    private final static Integer COMPETENT_ORG_TYPE = 1;
    //虚拟单位类型
    private final static Integer VIRTUAL_ORG_TYPE = 3;

    private final static String YUANSHUI_NAME = "宁波原水有限公司";

    private final static String DONGTOU_UUID = "57a876983bc44c15a94cc2f78359124a";

    private final static Date DONGTOU_DATE = DateUtil.parse("2022-12", DateUtil.PATTERN_MONTH);

    private final static String ROOT_PARENT_ID = "0";

    @Override
    public List<Org> getAllChild(String id) {
        if (StringUtil.isBlank(id)) {
            return null;
        }
        Org org = getById(id);
        if (org == null) {
            return null;
        }
        return list(new LambdaQueryWrapper<Org>().ne(Org::getIsDel, IS_DEL).likeRight(Org::getOrgCode, org.getOrgCode()));
    }

    @Override
    public List<String> getAllChildIds(String id) {
        return getAllChild(id).stream().map(Org::getId).collect(Collectors.toList());
    }

    @Override
    public Boolean checkIsGzw(String id) {
        if (StringUtil.isBlank(id)) {
            return false;
        }
        Org org = getById(id);
        if (org == null) {
            return false;
        }
        return gzwProperties.getName().equals(org.getName());
    }

    @Override
    public Boolean checkIsGzw(Org org) {
        return gzwProperties.getName().equals(org.getName());
    }

    @Override
    public List<Org> getChildOrg(String id) {
        if (StringUtil.isBlank(id)) {
            return null;
        }
        return list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getParentId, id)
                .orderByAsc(Org::getOrderNum));
    }

    @Override
    public List<Org> getChildOrg(List<String> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return null;
        }
        return list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .in(Org::getParentId, ids)
                .orderByAsc(Org::getOrderNum));
    }


    @Override
    public Map<String, List<String>> getChildOrg(List<Org> parentOrgList, List<Org> allOrg) {
        HashMap<String, List<String>> map = new HashMap<>(parentOrgList.size());
        HashMap<String, String> orgCodeIdMap = new HashMap<>(parentOrgList.size());
        List<String> parentOrgCodeList = new ArrayList<>();
        for (Org parentOrg : parentOrgList) {
            map.put(parentOrg.getId(), new ArrayList<>());
            orgCodeIdMap.put(parentOrg.getOrgCode(), parentOrg.getId());
            parentOrgCodeList.add(parentOrg.getOrgCode());
        }

        for (Org org : allOrg) {
            for (String parentOrgCode : parentOrgCodeList) {
                if (org.getOrgCode().equals(parentOrgCode) || org.getOrgCode().startsWith(parentOrgCode)) {
                    List<String> childIds = map.get(orgCodeIdMap.get(parentOrgCode));
                    childIds.add(org.getId());
                }
            }
        }

        return map;
    }

    @Override
    public List<Org> getGzwUnits() {
        return list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getIsUnit, IS_UNIT)
                .eq(Org::getForGzw, FOR_GZW)
                .orderByAsc(Org::getOrderNum));
    }

    @Override
    public List<Org> getGzwUnits(boolean flag) {
        return list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getIsUnit, IS_UNIT)
                .eq(Org::getForGzw, FOR_GZW)
                .ne(flag, Org::getId, DONGTOU_UUID)
                .orderByAsc(Org::getOrderNum));
    }

    @Override
    public boolean getDTFlag(String countDate) {
        Date date = DateUtil.parse(countDate, DateUtil.PATTERN_MONTH);
        return date.getTime() >=  DONGTOU_DATE.getTime();
    }

    @Override
    public boolean isDT(String orgId) {
        return DONGTOU_UUID.equals(orgId);
    }

    @Override
    public List<Org> getAllOrg() {
        return list(new LambdaQueryWrapper<Org>().ne(Org::getIsDel, IS_DEL));
    }

    @Override
    public List<Org> directlyUnderUnit() {
        return list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getIsMonitor, IS_MONITOR)
                .eq(Org::getType, UNIT_TYPE));
    }

    @Override
    public List<Org> directlyUnderChildUnit() {
        List<Org> directlyUnderUnitOrgList = list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getIsMonitor, IS_MONITOR)
                .eq(Org::getType, UNIT_TYPE));
        List<String> unitCodeList = directlyUnderUnitOrgList.stream().map(Org::getOrgCode).collect(Collectors.toList());
        List<Org> orgList = list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .likeRight(Org::getOrgCode, JGQY_ORG_CODE));
        List<Org> results = new ArrayList<>();
        for (Org org : orgList) {
            if (org.getOrgCode().length() >= 12 && unitCodeList.contains(org.getOrgCode().substring(0, 10))) {
                org.setUnitOrgCode(org.getOrgCode().substring(0, 10));
                results.add(org);
                continue;
            }

            if (org.getOrgCode().length() >= 10 && unitCodeList.contains(org.getOrgCode().substring(0, 8))) {
                org.setUnitOrgCode(org.getOrgCode().substring(0, 8));
                results.add(org);
                continue;
            }
        }

        return results;
    }

    @Override
    public ListResult<Org> directlyUnderUnitNoChild(Boolean result) {
        List<Org> list = list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
//                .eq(Org::getIsMonitor, IS_MONITOR)//数据库这个字段为null不知道具体业务
                .eq(Org::getParentId, gzwProperties.getReportId())
                .orderByAsc(Org::getOrderNum));
        if (result) {
            //判断登陆用户
            String orgId = TokenUtil.getTokenOrgId();
            result = orgId.equals(gzwProperties.getId()) || orgId.equals(gzwProperties.getReportId());
            if (!result) {
                list = list.stream().filter(org -> orgId.equals(org.getId())).collect(Collectors.toList());
            }
        }
        ListResult<Org> listResult = new ListResult(CommonCode.SUCCESS);
        listResult.setList(list);
        return listResult;
    }

//    @Override TODO DEL
//    public ListResult<Org> findThirteenOrgAddGZW() {
//        List<Org> list = list(new LambdaQueryWrapper<Org>()
//                .ne(Org::getIsDel, IS_DEL)
//                .eq(Org::getIsMonitor, IS_MONITOR)
//                .eq(Org::getParentId, gzwProperties.getReportId()));
//
//        //判断登陆用户
//        String orgId = TokenUtil.getTokenOrgId();
//        boolean result = orgId.equals(gzwProperties.getId()) || orgId.equals(gzwProperties.getReportId());
//        if (result) {
//            list.add(0,getById(gzwProperties.getId()));
//        }else {
//            list = list.stream().filter(org -> orgId.equals(org.getId())).collect(Collectors.toList());
//        }
//
//        ListResult<Org> listResult = new ListResult(CommonCode.SUCCESS);
//        listResult.setList(list);
//        return listResult;
//    }

    @Override
    public ListResult<Org> findThirteenOrgOfBackend() {
        ListResult<Org> listResult = new ListResult(CommonCode.SUCCESS);
        List<Org> list = list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getIsMonitor, IS_MONITOR)
                .eq(Org::getParentId, gzwProperties.getReportId()));
        listResult.setList(list);
        return listResult;
    }

    @Override
    public List<Org> findMainIndicatorsOrg() {
        String tokenOrgId = TokenUtil.getTokenOrgId();
        String reportId = gzwProperties.getReportId();
        if (checkIsGzw(tokenOrgId) || reportId.equals(tokenOrgId)){
            //国资账号 显示所有13家集团 加二级企业
            List<Org> results = new ArrayList<>();
            Org reportOrg = getById(reportId);
            List<Org> unitOrgList = list(new LambdaQueryWrapper<Org>()
                    .ne(Org::getIsDel, IS_DEL)
                    .eq(Org::getIsMonitor, IS_MONITOR)
                    .eq(Org::getParentId, reportId)
                    .orderByAsc(Org::getOrderNum));
            //虚拟合并节点
            List<String> virtualOrgIds = unitOrgList.stream()
                    .filter(org -> VIRTUAL_ORG_TYPE == org.getType()).map(Org::getId).collect(Collectors.toList());
            results.add(reportOrg);
            results.addAll(unitOrgList);
            List<Org> childOrgList = getChildOrg(unitOrgList.stream().map(Org::getId).collect(Collectors.toList()));
            results.addAll(childOrgList);
            List<String> childUnitOrgIds = childOrgList.stream()
                    .filter(org -> virtualOrgIds.contains(org.getParentId())).map(Org::getId).collect(Collectors.toList());
            results.addAll(getChildOrg(childUnitOrgIds));
//            for (Org org : results){
//                if (YUANSHUI_NAME.equals(org.getName())){
//                    org.setParentId(reportId);
//                    break;
//                }
//            }
            return results;
        }else {
            Org tokenOrg = getById(tokenOrgId);
            if (VIRTUAL_ORG_TYPE == tokenOrg.getType()){
                // 城投合并 广电合并
                List<Org> childUnitOrgList = getChildOrg(tokenOrgId);
                List<Org> results = new ArrayList<>();
                results.add(tokenOrg);
                results.addAll(childUnitOrgList);
                results.addAll(getChildOrg(childUnitOrgList.stream().map(Org::getId).collect(Collectors.toList())));
                return results;
            }
            if (!IS_UNIT.equals(tokenOrg.getIsUnit())){
                return Stream.of(tokenOrg).collect(Collectors.toList());
            }
            List<Org> orgList = getChildOrg(tokenOrgId);
            orgList.add(tokenOrg);
            return orgList;
        }
    }

    @Override
    public List<Org> findMainIndicatorsSummaryOrg() {
        String reportId = gzwProperties.getReportId();
        List<Org> unitOrgList = list(new LambdaQueryWrapper<Org>()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getIsMonitor, IS_MONITOR)
                .eq(Org::getParentId, reportId));
        unitOrgList.add(getOne(Wrappers.<Org>lambdaQuery().eq(Org::getName, YUANSHUI_NAME).ne(Org::getIsDel, IS_DEL)));
        return unitOrgList;
    }

    @Override
    public List<OrgVO> findMainIndicatorsOrgTree() {
        return ForestNodeMerger.merge(orgWrapper.entityToVO(findMainIndicatorsOrg()));
    }

    @Override
    public Org getByDataSourceId(String dataSource, String dataSourceId) {
        return getOne(Wrappers.<Org>lambdaQuery()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getDataSource, dataSource)
                .eq(Org::getDataSourceId, dataSourceId));
    }

    @Override
    public List<Org> getByDataSourceIds(String dataSource, List<String> dataSourceIds) {
        return list(Wrappers.<Org>lambdaQuery()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getDataSource, dataSource)
                .in(Org::getDataSourceId, dataSourceIds));
    }

    @Override
    public String ythOrgSubmitList(String data) {
        List<OrgVO> orgVOList = JSON.parseArray(data, OrgVO.class);
        List<Org> allOldOrgList = list(Wrappers.<Org>lambdaQuery()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getForGzw, FOR_GZW));
        Map<String, Org> orgNameMap = allOldOrgList.stream()
                .collect(Collectors.toMap(Org::getName, org -> org));
        Map<String, Org> dataSourceIdMap = allOldOrgList.stream().filter(org -> YthConstant.DATA_NINGBO.equals(org.getDataSource()))
                .collect(Collectors.toMap(Org::getDataSourceId, org -> org));
        List<Org> submitOrgList = new ArrayList<>();
        Date now = DateUtil.now();
        List<String> transferataSourceIds = orgVOList.stream().map(OrgVO::getDataSourceId).collect(Collectors.toList());
        Map<String, String> dataSourceIdParentMap = new HashMap<>();
        List<String> successIds = new ArrayList<>();
        List<String> failIds = new ArrayList<>();
        for (OrgVO orgVO : orgVOList){
            if (!dataSourceIdMap.containsKey(orgVO.getParentDataSourceId()) &&
                    !transferataSourceIds.contains(orgVO.getParentDataSourceId())){
                failIds.add(orgVO.getDataSourceId());
                continue;
            }
            dataSourceIdParentMap.put(orgVO.getDataSourceId(), orgVO.getParentDataSourceId());
            if (orgNameMap.containsKey(orgVO.getOrgName())){
                //根据名称匹配
                Org org = orgNameMap.get(orgVO.getOrgName());
                org.setDataSourceId(orgVO.getDataSourceId());
                org.setDataSource(YthConstant.DATA_NINGBO);
                org.setUpdateTime(now);
                submitOrgList.add(org);
                continue;
            }

            if (dataSourceIdMap.containsKey(orgVO.getDataSourceId())){
                //根据dataSourceId匹配
                Org org = dataSourceIdMap.get(orgVO.getDataSourceId());
                org.setName(orgVO.getOrgName());
                submitOrgList.add(org);
                continue;
            }

            Org org = orgWrapper.voToEntity(orgVO);
            org.setForGzw(FOR_GZW);
            org.setStatus("0");
            org.setName(orgVO.getOrgName());
            org.setDataSource(YthConstant.DATA_NINGBO);
            org.setCreateTime(now);
            org.setType(2);
            org.setOrderNum(9999);
            org.setIsUnit("0");
            org.setTypeCode("0");
            submitOrgList.add(org);
            successIds.add(orgVO.getDataSourceId());
        }

        if (CollectionUtil.isNotEmpty(submitOrgList)){
            saveOrUpdateBatch(submitOrgList);
            Map<String, String> dataSourceIdOrgIdMap = submitOrgList.stream().collect(Collectors.toMap(Org::getDataSourceId, Org::getId));
            List<Org> updateOrgCodeList = new ArrayList<>();
            for (Org org : submitOrgList){
                String parentDataSourceId = dataSourceIdParentMap.get(org.getDataSourceId());
                if (dataSourceIdMap.containsKey(parentDataSourceId)){
                    //已存在的数据
                    String parentId = dataSourceIdMap.get(parentDataSourceId).getId();
                    if (!parentId.equals(org.getParentId())){
                        org.setParentId(parentId);
                        updateOrgCodeList.add(org);
                        continue;
                    }
                }
                if (dataSourceIdOrgIdMap.containsKey(parentDataSourceId)){
                    //新传的数据
                    String parentId = dataSourceIdOrgIdMap.get(parentDataSourceId);
                    if (!parentId.equals(org.getParentId())){
                        org.setParentId(parentId);
                        updateOrgCodeList.add(org);
                        continue;
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(updateOrgCodeList)){
                List<Org> allOrgList = list(Wrappers.<Org>lambdaQuery()
                        .ne(Org::getIsDel, IS_DEL)
                        .eq(Org::getForGzw, FOR_GZW));
                Map<String, Org> orgIdMap = allOrgList.stream().collect(Collectors.toMap(Org::getId, org -> org));
                Map<String, Org> updateOrgCodeIdMap = updateOrgCodeList.stream().collect(Collectors.toMap(Org::getId, org -> org));
                for (Org org : updateOrgCodeList){
                    org.setOrgCode(createOrgCode(org, allOrgList, orgIdMap, updateOrgCodeIdMap));
                }
                saveOrUpdateBatch(updateOrgCodeList);
            }
        }

        return JSON.toJSONString(YthResult.builder().successIds(successIds).failIds(failIds).failReason(CollectionUtil.isNotEmpty(failIds) ? "父节点不存在" : null).build());
    }

    @Override
    public List<Org> getYthOrgList() {
        return list(Wrappers.<Org>lambdaQuery()
                .ne(Org::getIsDel, IS_DEL)
                .eq(Org::getDataSource, YthConstant.DATA_NINGBO)
                .eq(Org::getForGzw, FOR_GZW));
    }

    private String createOrgCode(Org org, List<Org> allOrgList, Map<String, Org> orgIdMap, Map<String, Org> updateOrgCodeIdMap){
        if (!orgIdMap.containsKey(org.getParentId())){
            return null;
        }
        Org parentOrg = orgIdMap.get(org.getParentId());
        if (updateOrgCodeIdMap.containsKey(parentOrg.getId())){
            return createOrgCode(parentOrg, allOrgList, orgIdMap, updateOrgCodeIdMap);
        }
        List<Org> childOrgList = allOrgList.stream().filter(childOrg -> parentOrg.getId().equals(childOrg.getParentId())
                        && StringUtil.isNotBlank(childOrg.getOrgCode())
                        && childOrg.getOrgCode().substring(0, childOrg.getOrgCode().length() - 2).equals(parentOrg.getOrgCode()))
                .sorted(Comparator.comparing(Org::getOrgCode))
                .collect(Collectors.toList());
        if (CollectionUtil.isEmpty(childOrgList)){
            return parentOrg.getOrgCode() + "01";
        }
        String lastOrgCode = childOrgList.get(childOrgList.size() - 1).getOrgCode();
        int lastOrgCodeNum = Integer.valueOf(lastOrgCode.substring(lastOrgCode.length() - 2));
        if (lastOrgCodeNum < 9){
            return parentOrg.getOrgCode() + String.format("%02d", lastOrgCodeNum + 1);
        }
        return parentOrg.getOrgCode() + (lastOrgCodeNum + 1);
    }

    @Override
    public String ythOrgRemove(String data) {
        List<String> dataSourceIds = JSON.parseArray(data, String.class);
        if (CollectionUtil.isEmpty(dataSourceIds)){
            return JSON.toJSONString(YthResult.builder().build());
        }
        List<Org> oldOrgList = getByDataSourceIds(YthConstant.DATA_NINGBO, dataSourceIds);
        if (CollectionUtil.isEmpty(oldOrgList)){
            return JSON.toJSONString(YthResult.builder().failIds(dataSourceIds).failReason("企业不存在").build());
        }
        List<String> oldDataSourceIds = oldOrgList.stream().map(Org::getDataSourceId).collect(Collectors.toList());
        List<String> successIds = new ArrayList<>();
        List<String> failIds = new ArrayList<>();
        for (String dataSourceId : dataSourceIds){
            if (oldDataSourceIds.contains(dataSourceId)){
                successIds.add(dataSourceId);
            }else {
                failIds.add(dataSourceId);
            }
        }
        removeByIds(oldOrgList.stream().map(Org::getId).collect(Collectors.toList()));
        return JSON.toJSONString(YthResult.builder().successIds(successIds).failIds(failIds).failReason(CollectionUtil.isNotEmpty(failIds) ? "企业不存在" : null).build());

    }

    @Override
    public String ythOrgDetails(String data) {
        List<String> dataSourceIds = JSON.parseArray(data, String.class);
        if (CollectionUtil.isEmpty(dataSourceIds)){
            return JSON.toJSONString(new ArrayList<>());
        }
        List<Org> queryOrgList = getByDataSourceIds(YthConstant.DATA_NINGBO, dataSourceIds);
        if (CollectionUtil.isEmpty(queryOrgList)){
            return JSON.toJSONString(new ArrayList<>());
        }
        List<Org> allOrgList = getYthOrgList();
        Map<String, String> orgDataSourceMap = allOrgList.stream().collect(Collectors.toMap(Org::getId, Org::getDataSourceId));
        List<OrgVO> orgVOList = new ArrayList<>();
        for (Org org : queryOrgList){
            OrgVO orgVO = new OrgVO();
            orgVO.setOrgName(org.getName());
            orgVO.setDataSourceId(org.getDataSourceId());
            orgVO.setParentDataSourceId(orgDataSourceMap.get(org.getParentId()));
            orgVOList.add(orgVO);
        }
        return JSON.toJSONString(orgVOList);
    }

    @Override
    public boolean haveChild(String orgId) {
        return count(Wrappers.<Org>lambdaQuery().ne(Org::getIsDel, IS_DEL).eq(Org::getParentId, orgId)) > 0;
    }

    @Override
    public List<Org> getFinancingOrgList() {
        return list(new LambdaQueryWrapper<Org>()
                .eq(Org::getIsMonitor, IS_MONITOR)
                .eq(Org::getParentId, gzwProperties.getReportId())
                .orderByAsc(Org::getOrderNum));
    }

    @Override
    public List<OrgVO> findCheckName(List<Org> orgList) {
        PageData pd = new PageData();
        pd.put("orgIds", orgList.stream().map(Org::getId).collect(Collectors.toList()));
        List<OrgVO> orgVOList = orgWrapper.entityToVO(orgList);
        try {
            List<Enterprise> enterpriseList = enterpriseService.findByOrgIds(orgList.stream().map(Org::getId).collect(Collectors.toList()));
            if (CollectionUtil.isEmpty(enterpriseList)){
                return orgVOList;
            }
            Map<String, String> orgIdCheckNameMap = enterpriseList.stream().collect(Collectors.toMap(enterprise -> enterprise.getOrgId(),
                    enterprise -> enterprise.getUnitCheck()));
            for (OrgVO orgVO : orgVOList){
                orgVO.setOrgCheckName(orgIdCheckNameMap.getOrDefault(orgVO.getId(), null));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return orgVOList;
    }

    @Override
    public Map<String, String> getSourceId(){
        List<Org> orgList = list(new LambdaQueryWrapper<Org>().eq(Org::getDataSource, 3).eq(Org::getIsDel,0));
        return orgList.stream().collect(Collectors.toMap(Org::getDataSourceId, Org::getId));
    }

    /**
     * @Description: //TODO 返回上级
     * @Author: Take-off
     * @Date: 11:00 AM 2023/4/13
     * @Param: [id]
     * @return: com.plian.system.entity.sys.Org
     **/
    @Override
    public Org getSuperiorUnit(String id){
        Org org = getById(id);
        if (Optional.ofNullable(org.getIsUnit()).isPresent() && "1".equals(org.getIsUnit())){
            //集团返回国资委
            return getById(gzwProperties.getId());
        }else {
            return getById(org.getParentId());
        }
    }

    @Override
    public List<Org> getAllRegulatoryOrg() {
        Org reportOrg = getById(gzwProperties.getReportId());
        return list(Wrappers.<Org>lambdaQuery()
                .ne(Org::getIsDel, IS_DEL)
                .and(wrapper -> wrapper.likeRight(Org::getOrgCode, reportOrg.getOrgCode())
                        .or().in(Org::getId, Stream.of(reportOrg.getParentId(), gzwProperties.getId())
                                .collect(Collectors.toList()))));
    }


    @Override
    public int getSummaryCode(Org org) {
        if (StringUtil.isBlank(org.getParentId()) || ROOT_PARENT_ID.equals(org.getParentId())){
            return 0;
        }
        return (org.getOrgCode().length() / 2) - 1;
    }

    @Override
    public void checkAndChangeOrgCode() {
        List<Org> allOrg = getAllOrg();
        Map<String, Org> allOrgMap = allOrg.stream().collect(Collectors.toMap(Org::getId, Function.identity()));
        Map<String, List<Org>> parentOrgMap = allOrg.stream().collect(Collectors.groupingBy(Org::getParentId));
        List<Org> noParentList = new ArrayList<>();
        List<Org> changeOrgCodeList = new ArrayList<>();
        Map<Integer, List<Org>> levelMap = new HashMap<>();
        for (Org org : allOrg){
            if (StringUtil.isNotBlank(org.getParentId()) && !org.getParentId().equals(OrgConstant.DEFAULT_PARENT_ID)){
                if (allOrgMap.containsKey(org.getParentId())){
                    Org parentOrg = allOrgMap.get(org.getParentId());
                    if (!org.getOrgCode().startsWith(parentOrg.getOrgCode())
                            || org.getOrgCode().length() != parentOrg.getOrgCode().length() + 2){
                        int level = parentOrg.getOrgCode().length()/2;
                        List<Org> levelList = new ArrayList<>();
                        if (levelMap.containsKey(level)){
                            levelList = levelMap.get(level);
                        }
                        levelList.add(org);
                        levelMap.put(level, levelList);
                        changeOrgCodeList.add(org);
                    }
                }else {
                    noParentList.add(org);
                }
            }
        }
        if (CollectionUtil.isEmpty(changeOrgCodeList)){
            return;
        }
        Set<Integer> levelSet = levelMap.keySet().stream().sorted().collect(Collectors.toSet());
        List<Org> updateList = new ArrayList<>();
        for (Integer level : levelSet){
            List<Org> levelList = levelMap.get(level);
            for (Org org : levelList){
                Org parentOrg = allOrgMap.get(org.getParentId());
                List<Org> childOrgList = parentOrgMap.get(parentOrg.getId());
                int maxIndex = 0;
                for (Org childOrg : childOrgList){
                    if (childOrg.getOrgCode().startsWith(parentOrg.getOrgCode())
                            && childOrg.getOrgCode().length() == parentOrg.getOrgCode().length() + 2){
                        int tempIndex = Integer.valueOf(childOrg.getOrgCode().replace(parentOrg.getOrgCode(), ""));
                        if (tempIndex > maxIndex){
                            maxIndex = tempIndex;
                        }
                    }
                }
                String code = String.format("%02d", maxIndex+1);
                String orgCode = parentOrg.getOrgCode() + code;
                org.setOrgCode(orgCode);
                updateList.add(org);
            }
        }
        saveOrUpdateBatch(updateList);
    }

    @Override
    public List<Org> getAllCompetentOrganization() {
        return list(Wrappers.<Org>lambdaQuery()
                .eq(Org::getType, COMPETENT_ORG_TYPE)
                .ne(Org::getIsDel, IS_DEL));
    }
}
